package com.example.converter;

import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @version V1.0 字符串处理工具类。
 * @Title: StringHelper.java
 * @Package com.jarvis.base.utils
 * @Description:
 */
public final class StringHelper {
  
  /**
   * 描述： 构造方法
   */
  private StringHelper() {
  }
  
  /**
   * 空字符串
   */
  public static final String EMPTY_STRING = "";
  
  /**
   * 点
   */
  public static final char DOT = '.';
  
  /**
   * 下划线
   */
  public static final char UNDERSCORE = '_';
  
  /**
   * 逗点及空格
   */
  public static final String COMMA_SPACE = ", ";
  
  /**
   * 逗点
   */
  public static final String COMMA = ",";
  
  /**
   * 开始括号
   */
  public static final String OPEN_PAREN = "(";
  
  /**
   * 结束括号
   */
  public static final String CLOSE_PAREN = ")";
  
  /**
   * 单引号
   */
  public static final char SINGLE_QUOTE = '\'';
  
  /**
   * 回车
   */
  public static final String CRLF = "\r\n";
  
  /**
   * 常量 12
   */
  public static final int FIANL_TWELVE = 12;
  
  /**
   * 十六进制常量 0x80
   */
  public static final int HEX_80 = 0x80;
  
  /**
   * 十六进制常量 0xff
   */
  public static final int HEX_FF = 0xff;
  
  /**
   * 把字符数组，转化为一个字符
   *
   * @param seperator 字符分隔符
   * @param strings 数组对象
   * @return 字符串
   */
  public static String join(String seperator, String[] strings) {
    int length = strings.length;
    if (length == 0) {
      return EMPTY_STRING;
    }
    StringBuffer buf = new StringBuffer(length * strings[0].length()).append(strings[0]);
    for (int i = 1; i < length; i++) {
      buf.append(seperator).append(strings[i]);
    }
    return buf.toString();
  }
  
  /**
   * 把迭代对象转化为一个字符串
   *
   * @param seperator 分隔符
   * @param objects 迭代器对象
   * @return 字符串
   */
  public static String join(String seperator, Iterator<?> objects) {
    StringBuffer buf = new StringBuffer();
    if (objects.hasNext()) {
      buf.append(objects.next());
    }
    while (objects.hasNext()) {
      buf.append(seperator).append(objects.next());
    }
    return buf.toString();
  }
  
  /**
   * 把两个字符串数组的元素用分隔符连接，生成新的数组，生成的数组以第一个字符串数组为参照，与其长度相同。
   *
   * @param x 字符串数组
   * @param seperator 分隔符
   * @param y 字符串数组
   * @return 组合后的字符串数组
   */
  public static String[] add(String[] x, String seperator, String[] y) {
    String[] result = new String[x.length];
    for (int i = 0; i < x.length; i++) {
      result[i] = x[i] + seperator + y[i];
    }
    return result;
  }
  
  /**
   * 生成一个重复的字符串，如需要重复*10次，则生成：**********。
   *
   * @param string 重复元素
   * @param times 重复次数
   * @return 生成后的字符串
   */
  public static String repeat(String string, int times) {
    StringBuffer buf = new StringBuffer(string.length() * times);
    for (int i = 0; i < times; i++) {
      buf.append(string);
    }
    return buf.toString();
  }
  
  /**
   * 字符串替换处理，把旧的字符串替换为新的字符串，主要是通过字符串查找进行处理
   *
   * @param source 需要进行替换的字符串
   * @param old 需要进行替换的字符串
   * @param replace 替换成的字符串
   * @return 替换处理后的字符串
   */
  public static String replace(String source, String old, String replace) {
    StringBuffer output = new StringBuffer();
    
    int sourceLen = source.length();
    int oldLen = old.length();
    
    int posStart = 0;
    int pos;
    
    // 通过截取字符串的方式，替换字符串
    while ((pos = source.indexOf(old, posStart)) >= 0) {
      output.append(source.substring(posStart, pos));
      
      output.append(replace);
      posStart = pos + oldLen;
    }
    
    // 如果还有没有处理的字符串，则都添加到新字符串后面
    if (posStart < sourceLen) {
      output.append(source.substring(posStart));
    }
    
    return output.toString();
  }
  
  /**
   * 替换字符，如果指定进行全替换，必须设wholeWords=true，否则只替换最后出现的字符。
   *
   * @param template 字符模板
   * @param placeholder 需要替换的字符
   * @param replacement 新的字符
   * @param wholeWords 是否需要全替换，true为需要，false为不需要。如果不需要，则只替换最后出现的字符。
   * @return 替换后的新字符
   */
  public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
    int loc = template.indexOf(placeholder);
    if (loc < 0) {
      return template;
    } else {
      final boolean actuallyReplace = wholeWords || loc + placeholder.length() == template.length()
                                        || !Character.isJavaIdentifierPart(template.charAt(loc + placeholder.length()));
      String actualReplacement = actuallyReplace ? replacement : placeholder;
      return new StringBuffer(template.substring(0, loc)).append(actualReplacement).append(
        replace(template.substring(loc + placeholder.length()), placeholder, replacement, wholeWords))
               .toString();
    }
  }
  
  /**
   * 替换字符，只替换第一次出现的字符串。
   *
   * @param template 字符模板
   * @param placeholder 需要替换的字符串
   * @param replacement 新字符串
   * @return 替换后的字符串
   */
  public static String replaceOnce(String template, String placeholder, String replacement) {
    int loc = template.indexOf(placeholder);
    if (loc < 0) {
      return template;
    } else {
      return new StringBuffer(template.substring(0, loc)).append(replacement)
               .append(template.substring(loc + placeholder.length())).toString();
    }
  }
  
  /**
   * 把字符串，按指字的分隔符分隔为字符串数组
   *
   * @param seperators 分隔符
   * @param list 字符串
   * @return 字符串数组
   */
  public static String[] split(String list, String seperators) {
    return split(list, seperators, false);
  }
  
  /**
   * 把字符串，按指字的分隔符分隔为字符串数组
   *
   * @param seperators 分隔符
   * @param list 字符串
   * @param include 是否需要把分隔符也返回
   * @return 字符串数组
   */
  public static String[] split(String list, String seperators, boolean include) {
    StringTokenizer tokens = new StringTokenizer(list, seperators, include);
    String[] result = new String[tokens.countTokens()];
    int i = 0;
    while (tokens.hasMoreTokens()) {
      result[i++] = tokens.nextToken();
    }
    return result;
  }
  
  /**
   * 提取字符串中，以.为分隔符后的所有字符，如string.exe，将返回exe。
   *
   * @param qualifiedName 字符串
   * @return 提取后的字符串
   */
  public static String unqualify(String qualifiedName) {
    return unqualify(qualifiedName, ".");
  }
  
  /**
   * 提取字符串中，以指定分隔符后的所有字符，如string.exe，将返回exe。
   *
   * @param qualifiedName 字符串
   * @param seperator 分隔符
   * @return 提取后的字符串
   */
  public static String unqualify(String qualifiedName, String seperator) {
    return qualifiedName.substring(qualifiedName.lastIndexOf(seperator) + 1);
  }
  
  /**
   * 提取字符串中，以.为分隔符以前的字符，如string.exe，则返回string
   *
   * @param qualifiedName 字符串
   * @return 提取后的字符串
   */
  public static String qualifier(String qualifiedName) {
    int loc = qualifiedName.lastIndexOf(".");
    if (loc < 0) {
      return EMPTY_STRING;
    } else {
      return qualifiedName.substring(0, loc);
    }
  }
  
  /**
   * 向字符串数组中的所有元素添加上后缀
   *
   * @param columns 字符串数组
   * @param suffix 后缀
   * @return 添加后缀后的数组
   */
  public static String[] suffix(String[] columns, String suffix) {
    if (suffix == null) {
      return columns;
    }
    String[] qualified = new String[columns.length];
    for (int i = 0; i < columns.length; i++) {
      qualified[i] = suffix(columns[i], suffix);
    }
    return qualified;
  }
  
  /**
   * 向字符串加上后缀
   *
   * @param name 需要添加后缀的字符串
   * @param suffix 后缀
   * @return 添加后缀的字符串
   */
  public static String suffix(String name, String suffix) {
    return (suffix == null) ? name : name + suffix;
  }
  
  /**
   * 向字符串数组中的所有元素，添加上前缀
   *
   * @param columns 需要添加前缀的字符串数组
   * @param prefix prefix
   */
  public static String[] prefix(String[] columns, String prefix) {
    if (prefix == null) {
      return columns;
    }
    String[] qualified = new String[columns.length];
    for (int i = 0; i < columns.length; i++) {
      qualified[i] = prefix + columns[i];
    }
    return qualified;
  }
  
  /**
   * 向字符串添加上前缀
   *
   * @param name 需要添加前缀的字符串
   * @param prefix 前缀
   * @return 添加前缀后的字符串
   */
  public static String prefix(String name, String prefix) {
    return (prefix == null) ? name : prefix + name;
  }
  
  /**
   * 判断字符串是否为"true"、"t"，如果是，返回true，否则返回false
   *
   * @param tfString 需要进行判断真/假的字符串
   * @return true/false
   */
  public static boolean booleanValue(String tfString) {
    String trimmed = tfString.trim().toLowerCase();
    return trimmed.equals("true") || trimmed.equals("t");
  }
  
  /**
   * 把对象数组转化为字符串
   *
   * @param array 对象数组
   * @return 字符串
   */
  public static String toString(Object[] array) {
    int len = array.length;
    if (len == 0) {
      return StringHelper.EMPTY_STRING;
    }
    StringBuffer buf = new StringBuffer(len * FIANL_TWELVE);
    for (int i = 0; i < len - 1; i++) {
      buf.append(array[i]).append(StringHelper.COMMA_SPACE);
    }
    return buf.append(array[len - 1]).toString();
  }
  
  /**
   * 描述：把数组中的所有元素出现的字符串进行替换，把旧字符串替换为新字符数组的所有元素，只替换第一次出现的字符。
   *
   * @param string 需要替换的数组
   * @param placeholders 需要替换的字符串
   * @param replacements 新字符串数组
   * @return 替换后的字符串数组
   */
  public static String[] multiply(String string, Iterator<?> placeholders, Iterator<?> replacements) {
    String[] result = new String[]{string};
    while (placeholders.hasNext()) {
      result = multiply(result, (String) placeholders.next(), (String[]) replacements.next());
    }
    return result;
  }
  
  /**
   * 把数组中的所有元素出现的字符串进行替换，把旧字符串替换为新字符数组的所有元素，只替换第一次出现的字符。
   *
   * @param strings 需要替换的数组
   * @param placeholder 需要替换的字符串
   * @param replacements 新字符串数组
   * @return 替换后的字符串数组
   */
  private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
    String[] results = new String[replacements.length * strings.length];
    int n = 0;
    for (int i = 0; i < replacements.length; i++) {
      for (int j = 0; j < strings.length; j++) {
        results[n++] = replaceOnce(strings[j], placeholder, replacements[i]);
      }
    }
    return results;
  }
  
  /**
   * 统计Char在字符串中出现在次数，如"s"在字符串"string"中出现的次数
   *
   * @param string 字符串
   * @param character 需要进行统计的char
   * @return 数量
   */
  public static int count(String string, char character) {
    int n = 0;
    for (int i = 0; i < string.length(); i++) {
      if (string.charAt(i) == character) {
        n++;
      }
    }
    return n;
  }
  
  /**
   * 描述：计算字符串中未引用的字符
   *
   * @param string 字符串
   * @param character 字符
   * @return 未引用的字符数
   */
  public static int countUnquoted(String string, char character) {
    if (SINGLE_QUOTE == character) {
      throw new IllegalArgumentException("Unquoted count of quotes is invalid");
    }
    
    int count = 0;
    int stringLength = string == null ? 0 : string.length();
    boolean inQuote = false;
    for (int indx = 0; indx < stringLength; indx++) {
      if (inQuote) {
        if (SINGLE_QUOTE == string.charAt(indx)) {
          inQuote = false;
        }
      } else if (SINGLE_QUOTE == string.charAt(indx)) {
        inQuote = true;
      } else if (string.charAt(indx) == character) {
        count++;
      }
    }
    return count;
  }
  
  /**
   * 描述：描述：判断字符串是否为空，如果为true则为空。与isEmpty不同，如果字符为" "也视为空字符
   *
   * @param str 字符串
   */
  public static boolean isBlank(String str) {
    boolean b = true;// 20140507 modify by liwei 修复对" "为false的bug
    if (str == null) {
      b = true;
    } else {
      int strLen = str.length();
      if (strLen == 0) {
        b = true;
      }
      
      for (int i = 0; i < strLen; i++) {
        if (!Character.isWhitespace(str.charAt(i))) {
          b = false;
          break;
        }
      }
    }
    
    return b;
  }
  
  /**
   * 描述：描述：判断字符串是否为空，如果为true则不为空。与isNotEmpty不同，如果字符为" "也视为空字符
   *
   * @param str 字符串
   */
  public static boolean isNotBlank(String str) {
    int strLen = 0;
    if (str != null) {
      strLen = str.length();
    }
    if (str == null || strLen == 0) {
      return false;
    }
    for (int i = 0; i < strLen; i++) {
      if (!Character.isWhitespace(str.charAt(i))) {
        return true;
      }
    }
    
    return false;
  }
  
  /**
   * 判断字符串是否非空，如果为true则不为空
   *
   * @param string 字符串
   * @return true/false
   */
  public static boolean isNotEmpty(String string) {
    return string != null && string.length() > 0;
  }
  
  /**
   * 判断字符串是否空，如果为true则为空
   *
   * @param str 字符串
   * @return true/false
   */
  
  public static boolean isEmpty(String str) {
    if (str == null || str.trim().length() == 0) {
      return true;
    }
    return false;
  }
  
  /**
   * 向字符串添加上前缀，并以.作为分隔符
   *
   * @param name 需要添加前缀的字符串
   * @param prefix 前缀
   * @return 添加前缀后的字符串
   */
  public static String qualify(String name, String prefix) {
    if (name.startsWith("'")) {
      return name;
    }
    
    return new StringBuffer(prefix.length() + name.length() + 1).append(prefix).append(DOT).append(name).toString();
  }
  
  /**
   * 向字符串数组中的所有字符添加上前缀，前以点作为分隔符
   *
   * @param names 字符串数组
   * @param prefix 前缀
   * @return 添加前缀后的字符串数组
   */
  public static String[] qualify(String[] names, String prefix) {
    if (prefix == null) {
      return names;
    }
    int len = names.length;
    String[] qualified = new String[len];
    for (int i = 0; i < len; i++) {
      qualified[i] = qualify(prefix, names[i]);
    }
    return qualified;
  }
  
  /**
   * 在字符串中，查找字符第一次出现的位置
   *
   * @param sqlString 原字符串
   * @param string 需要查找到字符串
   * @param startindex 开始位置
   * @return 第一个出现的位置
   */
  public static int firstIndexOfChar(String sqlString, String string, int startindex) {
    int matchAt = -1;
    for (int i = 0; i < string.length(); i++) {
      int curMatch = sqlString.indexOf(string.charAt(i), startindex);
      if (curMatch >= 0) {
        if (matchAt == -1) {
          matchAt = curMatch;
        } else {
          matchAt = Math.min(matchAt, curMatch);
        }
      }
    }
    return matchAt;
  }
  
  /**
   * 从字符串中提取指字长度的字符。区分中英文。<br> 如果需要加省略号，则将在指定长度上少取3个字符宽度，末尾加上"......"。
   *
   * @param string 字符串
   * @param length 要取的字符长度，此为中文长度，英文仅当作半个字符。
   * @param appendSuspensionPoints 是否需要加省略号
   * @return 提取后的字符串
   */
  public static String truncate(String string, int length, boolean appendSuspensionPoints) {
    if (isEmpty(string) || length < 0) {
      return string;
    }
    
    if (length == 0) {
      return "";
    }
    
    int strLength = string.length(); // 字符串字符个数
    int byteLength = byteLength(string); // 字符串字节长度
    length *= 2; // 换成字节长度
    
    // 判断是否需要加省略号
    boolean needSus = false;
    if (appendSuspensionPoints && byteLength >= length) {
      needSus = true;
      
      // 如果需要加省略号，则要少取2个字节用来加省略号
      length -= 2;
    }
    
    StringBuffer result = new StringBuffer();
    int count = 0;
    for (int i = 0; i < strLength; i++) {
      if (count >= length) { // 取完了
        break;
      }
      
      char c = string.charAt(i);
      
      if (isLetter(c)) { // Ascill字符
        result.append(c);
        count += 1;
      } else { // 非Ascill字符
        if (count == length - 1) { // 如果只要取1个字节了，而后面1个是汉字，就放空格
          result.append(" ");
          count += 1;
        } else {
          result.append(c);
          count += 2;
        }
      }
    }
    
    if (needSus) {
      result.append("...");
    }
    
    return result.toString();
  }
  
  /**
   * 描述：判断一个字符是Ascill字符还是其它字符（如汉，日，韩文字符）
   *
   * @param c 需要判断的字符
   */
  public static boolean isLetter(char c) {
    int k = HEX_80;
    return c / k == 0 ? true : false;
  }
  
  /**
   * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
   *
   * @param s ,需要得到长度的字符串
   * @return int, 得到的字符串长度
   */
  public static int byteLength(String s) {
    char[] c = s.toCharArray();
    int len = 0;
    for (int i = 0; i < c.length; i++) {
      if (isLetter(c[i])) {
        len++;
      } else {
        len += 2;
      }
    }
    return len;
  }
  
  /**
   * 从字符串中提取指字长度的字符
   *
   * @param string 字符串
   * @param length 字符长度
   * @return 提取后的字符串
   */
  public static String truncate(String string, int length) {
    if (isEmpty(string)) {
      return string;
    }
    
    if (string.length() <= length) {
      return string;
    } else {
      return string.substring(0, length);
    }
  }
  
  /**
   * 去丢字符的左侧空格
   *
   * @param value 字符串
   * @return 去丢左侧空格后的字符串
   */
  public static String leftTrim(String value) {
    String result = value;
    if (result == null) {
      return result;
    }
    char ch[] = result.toCharArray();
    int index = -1;
    for (int i = 0; i < ch.length; i++) {
      if (!Character.isWhitespace(ch[i])) {
        break;
      }
      index = i;
    }
    
    if (index != -1) {
      result = result.substring(index + 1);
    }
    return result;
  }
  
  /**
   * 去丢字符的右侧空格
   *
   * @param value 字符串
   * @return 去右侧空格后的字符串
   */
  public static String rightTrim(String value) {
    String result = value;
    if (result == null) {
      return result;
    }
    char ch[] = result.toCharArray();
    int endIndex = -1;
    for (int i = ch.length - 1; i > -1; i--) {
      if (!Character.isWhitespace(ch[i])) {
        break;
      }
      endIndex = i;
    }
    
    if (endIndex != -1) {
      result = result.substring(0, endIndex);
    }
    return result;
  }
  
  /**
   * 把null字符串转化为""
   *
   * @param source 空字符串
   * @return 转化后的字符串
   */
  public static String n2s(String source) {
    return source != null ? source : "";
  }
  
  /**
   * 如果字符串为空，则返回默认字符串
   *
   * @param source 源字符串
   * @param defaultStr 默认字符串
   * @return 转换后的字符串
   */
  public static String n2s(String source, String defaultStr) {
    return source != null ? source : defaultStr;
  }
  
  /**
   * 将字符串格式化成 HTML 以SCRIPT变量 主要是替换单,双引号，以将内容格式化输出，适合于 HTML 中的显示输出
   *
   * @param str 要格式化的字符串
   * @return 格式化后的字符串
   */
  public static String toScript(String str) {
    if (str == null) {
      return null;
    }
    
    String html = new String(str);
    
    html = replace(html, "\"", "\\\"");
    html = replace(html, "\r\n", "\n");
    html = replace(html, "\n", "\\n");
    html = replace(html, "\t", " ");
    html = replace(html, "\'", "\\\'");
    
    html = replace(html, " ", "  ");
    
    html = replace(html, "</script>", "<\\/script>");
    html = replace(html, "</SCRIPT>", "<\\/SCRIPT>");
    
    return html;
  }
  
  /**
   * 同于String#trim()，但是检测null，如果原字符串为null，则仍然返回null
   *
   * @param s s
   */
  public static String trim(String s) {
    return s == null ? s : s.trim();
  }
  
  /**
   * 对字符串进行空格处理，如果字符串为null呀是空字符串， 则返回默认的数字。
   *
   * @param source 需要进行处理的字符串
   * @param defaultValue 缺省值
   * @return 字符串的数字值
   */
  public static int strTrim(String source, int defaultValue) {
    if (isEmpty(source)) {
      return defaultValue;
    }
    try {
      source = source.trim();
      int value = (new Integer(source)).intValue();
      return value;
    } catch (Exception ex) {
      ex.printStackTrace();
      System.err.println("数字转换出错，请检查数据来源。返回默认值");
      return defaultValue;
    }
  }
  
  /**
   * 对字符串进行过滤处理，如果字符串是null或为空字符串， 返回默认值。
   *
   * @param source 需要进行处理的字符串
   * @param defaultValue 缺省值
   * @return 过滤后的字符串
   */
  public static String strTrim(String source, String defaultValue) {
    if (StringHelper.isEmpty(source)) {
      return defaultValue;
    }
    try {
      source = source.trim();
      return source;
    } catch (Exception ex) {
      ex.printStackTrace();
      System.err.println("字符串去空格失败，返回默认值");
      return defaultValue;
    }
  }
  
  /**
   * 描述：为了防止跨站脚本攻击，转换<>这种尖括号。
   */
  public static String encodeURL(String source) {
    if (source == null) {
      return null;
    }
    String html = new String(source);
    html = replace(html, "<", "<");
    html = replace(html, ">", ">");
    html = replace(html, "\"", "\"");
    html = replace(html, " ", " ");
    html = replace(html, "\'", "´");
    html = replace(html, "\\", "\\");
    html = replace(html, "&", "&");
    html = replace(html, "\r", "");
    html = replace(html, "\n", "");
    html = replace(html, "(", "(");
    html = replace(html, ")", ")");
    html = replace(html, "[", "[");
    html = replace(html, "]", "]");
    html = replace(html, ";", ";");
    html = replace(html, "/", "/");
    
    return html;
  }
  
  /**
   * 把字符串中一些特定的字符转换成html字符，如&、<、>、"号等
   *
   * @param source 需要进行处理的字符串
   * @return 处理后的字符串
   */
  public static String encodeHtml(String source) {
    if (source == null) {
      return null;
    }
    
    String html = new String(source);
    
    html = replace(html, "&", "&");
    html = replace(html, "<", "<");
    html = replace(html, ">", ">");
    html = replace(html, "\"", "\"");
    html = replace(html, " ", " ");
    html = replace(html, "\'", "´");
    return html;
  }
  
  /**
   * 把一些html的字符串还原
   *
   * @param source 需要进行处理的字符串
   * @return 处理后的字符串
   */
  public static String decodeHtml(String source) {
    if (source == null) {
      return null;
    }
    
    String html = new String(source);
    
    html = replace(html, "&", "&");
    html = replace(html, "<", "<");
    html = replace(html, ">", ">");
    html = replace(html, "\"", "\"");
    html = replace(html, " ", " ");
    
    html = replace(html, "\r\n", "\n");
    html = replace(html, "\n", "<br>\n");
    html = replace(html, "\t", " ");
    html = replace(html, " ", "  ");
    
    return html;
  }
  
  /**
   * 判断字符串是否为布尔值，如true/false等
   *
   * @param source 需要进行判断的字符串
   * @return 返回字符串的布尔值
   */
  public static boolean isBoolean(String source) {
    if (source.equalsIgnoreCase("true") || source.equalsIgnoreCase("false")) {
      return true;
    }
    return false;
  }
  
  /**
   * 去除字符串中的最后字符
   *
   * @param str 原字符串
   * @param strMove 要去除字符 比如","
   * @return 去除后的字符串
   */
  public static String lastCharTrim(String str, String strMove) {
    if (isEmpty(str)) {
      return "";
    }
    
    String newStr = "";
    if (str.lastIndexOf(strMove) != -1 && str.lastIndexOf(strMove) == str.length() - 1) {
      newStr = str.substring(0, str.lastIndexOf(strMove));
    }
    return newStr;
  }
  
  /**
   * 清除字符串里的html代码
   *
   * @param html 需要进行处理的字符串
   * @return 清除html后的代码
   */
  public static String clearHtml(String html) {
    if (isEmpty(html)) {
      return "";
    }
    
    String patternStr = "(<[^>]*>)";
    Pattern pattern = Pattern.compile(patternStr, Pattern.CASE_INSENSITIVE);
    Matcher matcher = null;
    StringBuffer bf = new StringBuffer();
    try {
      matcher = pattern.matcher(html);
      boolean first = true;
      int start = 0;
      int end = 0;
      while (matcher.find()) {
        start = matcher.start(1);
        if (first) {
          bf.append(html.substring(0, start));
          first = false;
        } else {
          bf.append(html.substring(end, start));
        }
        
        end = matcher.end(1);
      }
      if (end < html.length()) {
        bf.append(html.substring(end));
      }
      html = bf.toString();
      return html;
    } catch (Exception ex) {
      ex.printStackTrace();
      System.err.println("清除html标签失败");
    } finally {
      pattern = null;
      matcher = null;
    }
    return html;
  }
  
  /**
   * 把文杯格式转换为html格式
   *
   * @param content 转换的内容
   */
  public static String textFmtToHtmlFmt(String content) {
    content = StringHelper.replace(content, " ", " ");
    content = StringHelper.replace(content, "\r\n", "<br>");
    content = StringHelper.replace(content, "\n", "<br>");
    
    return content;
  }
  
  /**
   * 描述：大写英文字母转换成小写
   *
   * @param strIn 字符串参数
   */
  public static String toLowerStr(String strIn) {
    String strOut = new String(); // 输出的字串
    int len = strIn.length(); // 参数的长度
    int i = 0; // 计数器
    char ch; // 存放参数的字符
    
    while (i < len) {
      ch = strIn.charAt(i);
      
      if (ch >= 'A' && ch <= 'Z') {
        ch = (char) (ch - 'A' + 'a');
      }
      
      strOut += ch;
      i++;
    }
    return strOut;
  }
  
  /**
   * 描述：小写英文字母转换成大写
   *
   * @param strIn 字符串参数
   */
  public static String toUpperStr(String strIn) {
    String strOut = new String(); // 输出的字串
    int len = strIn.length(); // 参数的长度
    int i = 0; // 计数器
    char ch; // 存放参数的字符
    
    while (i < len) {
      ch = strIn.charAt(i);
      
      if (ch >= 'a' && ch <= 'z') {
        ch = (char) (ch - 'a' + 'A');
      }
      
      strOut += ch;
      i++;
    }
    return strOut;
  }
  
  /**
   * 货币缩写,提供亿和万两个单位，并精确到小数点2位 切换到新的算法:对数算法
   */
  public static String currencyShortFor(String original) {
    if (StringHelper.isBlank(original)) {
      return "";
    } else {
      String shortFor = "";
      double shortForValue = 0;
      DecimalFormat df = new DecimalFormat("#.00");
      
      try {
        double account = Double.parseDouble(original);
        if (account / 100000000 > 1) {
          shortForValue = account / 100000000;
          shortFor = df.format(shortForValue) + "亿";
        } else if (account / 10000 > 1) {
          shortForValue = account / 10000;
          shortFor = df.format(shortForValue) + "万";
        } else {
          shortFor = original;
        }
      } catch (NumberFormatException e) {
        e.printStackTrace();
        System.err.println("字符串[" + original + "]转换成数字出错");
      }
      
      return shortFor;
    }
  }
  
  /**
   * 将日期格式由yyyyMMdd装换为yyyy-MM-dd
   *
   * @param date Date string whose format is yyyyMMdd.
   */
  public static String formatDate(String date) {
    if (isBlank(date) || date.length() < 8) {
      return "";
    }
    StringBuffer dateBuf = new StringBuffer();
    dateBuf.append(date.substring(0, 4));
    dateBuf.append("-");
    dateBuf.append(date.substring(4, 6));
    dateBuf.append("-");
    dateBuf.append(date.substring(6, 8));
    return dateBuf.toString();
  }
  
  /**
   * 判断是否为整数
   *
   * @param str 传入的字符串
   * @return 是整数返回true, 否则返回false
   */
  public static boolean isInteger(String str) {
    Pattern pattern = Pattern.compile("^\\d+(\\.0)?$", Pattern.CASE_INSENSITIVE);
    return pattern.matcher(str).matches();
    
  }
  
  /**
   * 用于=中英文混排标题中限定字符串长度。保证显示长度最多只相差一个全角字符。
   *
   * @param string 需要截取的字符串
   * @param byteCount 字节数（度量标准为中文为两个字节，ASCII字符为一个字节,这样子，刚好匹配ASCII为半角字符，而中文为全角字符， 保证在网页上中英文混合的句子长度一致）
   */
  public static String substring(String string, int byteCount) throws UnsupportedEncodingException {
    if (isBlank(string)) {
      return string;
    }
    byte[] bytes = string.getBytes("Unicode");// 使用UCS-2编码.
    int viewBytes = 0; // 表示当前的字节数(英文为单字节，中文为双字节的表示方法)
    int ucs2Bytes = 2; // 要截取的字节数，从第3个字节开始,前两位为位序。（UCS-2的表示方法）
    // UCS-2每个字符使用两个字节来编码。
    // ASCII n+=1,i+=2
    // 中文 n+=2,i+=2
    for (; ucs2Bytes < bytes.length && viewBytes < byteCount; ucs2Bytes++) {
      // 奇数位置，如3、5、7等，为UCS2编码中两个字节的第二个字节
      if (ucs2Bytes % 2 == 1) {
        viewBytes++; // 低字节，无论中英文，都算一个字节。
      } else {
        // 当UCS2编码的第一个字节不等于0时，该UCS2字符为汉字，一个汉字算两个字节
        // 高位时，仅中文的高位算一字节。
        if (bytes[ucs2Bytes] != 0) {
          viewBytes++;
        }
      }
    }
    // 截一半的汉字要保留
    if (ucs2Bytes % 2 == 1) {
      ucs2Bytes = ucs2Bytes + 1;
    }
    String result = new String(bytes, 0, ucs2Bytes, "Unicode");// 将字节流转换为java默认编码UTF-8的字符串
    if (bytes.length > ucs2Bytes) {
      result += "...";
    }
    return result;
  }
  
  /**
   * 描述：根据长度截断字串
   *
   * @param str 字串
   * @param length 截取长度
   */
  public static String[] splite(String str, int length) {
    if (StringHelper.isEmpty(str)) {
      return null;
    }
    String[] strArr = new String[(str.length() + length - 1) / length];
    for (int i = 0; i < strArr.length; i++) {
      if (str.length() > i * length + length - 1) {
        strArr[i] = str.substring(i * length, i * length + length - 1);
      } else {
        strArr[i] = str.substring(i * length);
      }
    }
    return strArr;
  }
  
  /**
   * 描述：把某一个字符变成大写
   *
   * @param str str 字串
   * @param index 第几个字符
   */
  public static String toUpOneChar(String str, int index) {
    return toUpOrLowOneChar(str, index, 1);
  }
  
  /**
   * 描述：把某一个字符变成小写 作者：李建 时间：Dec 17, 2010 9:42:32 PM
   *
   * @param str str 字串
   * @param index 第几个字符
   */
  public static String toLowOneChar(String str, int index) {
    return toUpOrLowOneChar(str, index, 0);
  }
  
  /**
   * 描述：把某一个字符变成大写或小写 作者：李建 时间：Dec 17, 2010 9:39:32 PM
   *
   * @param str 字串
   * @param index 第几个字符
   * @param upOrLow 大小写 1：大写；0小写
   */
  public static String toUpOrLowOneChar(String str, int index, int upOrLow) {
    if (StringHelper.isNotEmpty(str) && index > -1 && index < str.length()) {
      char[] chars = str.toCharArray();
      if (upOrLow == 1) {
        chars[index] = Character.toUpperCase(chars[index]);
      } else {
        chars[index] = Character.toLowerCase(chars[index]);
      }
      return new String(chars);
    }
    return str;
  }
  
  /**
   * 将字符串用分隔符断裂成字符串列表
   *
   * @param value 原字符串
   * @param separator 分隔字符
   * @return 结果列表
   */
  public static List<String> split2List(String value, String separator) {
    List<String> ls = new ArrayList<String>();
    int i = 0, j = 0;
    while ((i = value.indexOf(separator, i)) != -1) {
      ls.add(value.substring(j, i));
      ++i;
      j = i;
    }
    ls.add(value.substring(j));
    return ls;
  }
  
  /**
   * 将数组用分隔符连接成新字符串(split的逆方法)
   *
   * @param strs 字符串数组
   * @param sep 分隔符
   * @return 结果字符串
   */
  public static String join(String[] strs, String sep) {
    StringBuilder res = new StringBuilder();
    for (int i = 0; i < strs.length; i++) {
      res.append(strs[i] + sep);
    }
    return res.substring(0, res.length() - sep.length());
  }
  
  /**
   * 获得一个UUID
   *
   * @return String UUID
   */
  public static String getUUID() {
    String str = UUID.randomUUID().toString();// 标准的UUID格式为：xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx(8-4-4-4-12)
    // 去掉"-"符号，不用replaceAll的原因与split一样，replaceAll支持正则表达式，频繁使用时效率不够高(当然偶尔用一下影响也不会特别严重)
    return join(split(str, "-"), "");
  }
  
  /**
   * <pre>
   * 例： String strVal="This is a dog"; String
   * strResult=CTools.replace(strVal,"dog","cat"); 结果： strResult equals
   * "This is cat"
   *
   * @param strSrc
   *  要进行替换操作的字符串
   * @param strOld
   *  要查找的字符串
   * @param strNew
   *  要替换的字符串
   * @return 替换后的字符串
   *
   *  <pre>
   */
  public static final String replaceAllStr(String strSrc, String strOld, String strNew) {
    if (strSrc == null || strOld == null || strNew == null) {
      return "";
    }
    int i = 0;
    // 避免新旧字符一样产生死循环
    if (strOld.equals(strNew)) {
      return strSrc;
    }
    
    if ((i = strSrc.indexOf(strOld, i)) >= 0) {
      char[] arr_cSrc = strSrc.toCharArray();
      char[] arr_cNew = strNew.toCharArray();
      
      int intOldLen = strOld.length();
      StringBuffer buf = new StringBuffer(arr_cSrc.length);
      buf.append(arr_cSrc, 0, i).append(arr_cNew);
      
      i += intOldLen;
      int j = i;
      
      while ((i = strSrc.indexOf(strOld, i)) > 0) {
        buf.append(arr_cSrc, j, i - j).append(arr_cNew);
        i += intOldLen;
        j = i;
      }
      
      buf.append(arr_cSrc, j, arr_cSrc.length - j);
      
      return buf.toString();
    }
    
    return strSrc;
  }
  
  /**
   * 用于将字符串中的特殊字符转换成Web页中可以安全显示的字符串 可对表单数据据进行处理对一些页面特殊字符进行处理如' <','>','"',''','&'
   *
   * @param strSrc 要进行替换操作的字符串
   * @return 替换特殊字符后的字符串
   * @since 1.0
   */
  
  public static String htmlEncode(String strSrc) {
    if (strSrc == null) {
      return "";
    }
    
    char[] arr_cSrc = strSrc.toCharArray();
    StringBuffer buf = new StringBuffer(arr_cSrc.length);
    char ch;
    
    for (int i = 0; i < arr_cSrc.length; i++) {
      ch = arr_cSrc[i];
      
      if (ch == '<') {
        buf.append("<");
      } else if (ch == '>') {
        buf.append(">");
      } else if (ch == '"') {
        buf.append("\"");
      } else if (ch == '\'') {
        buf.append("'");
      } else if (ch == '&') {
        buf.append("&");
      } else {
        buf.append(ch);
      }
    }
    
    return buf.toString();
  }
  
  /**
   * 用于将字符串中的特殊字符转换成Web页中可以安全显示的字符串 可对表单数据据进行处理对一些页面特殊字符进行处理如' <','>','"',''','&'
   *
   * @param strSrc 要进行替换操作的字符串
   * @param quotes 为0时单引号和双引号都替换，为1时不替换单引号，为2时不替换双引号，为3时单引号和双引号都不替换
   * @return 替换特殊字符后的字符串
   * @since 1.0
   */
  public static String htmlEncode(String strSrc, int quotes) {
    
    if (strSrc == null) {
      return "";
    }
    if (quotes == 0) {
      return htmlEncode(strSrc);
    }
    
    char[] arr_cSrc = strSrc.toCharArray();
    StringBuffer buf = new StringBuffer(arr_cSrc.length);
    char ch;
    
    for (int i = 0; i < arr_cSrc.length; i++) {
      ch = arr_cSrc[i];
      if (ch == '<') {
        buf.append("<");
      } else if (ch == '>') {
        buf.append(">");
      } else if (ch == '"' && quotes == 1) {
        buf.append("\"");
      } else if (ch == '\'' && quotes == 2) {
        buf.append("'");
      } else if (ch == '&') {
        buf.append("&");
      } else {
        buf.append(ch);
      }
    }
    
    return buf.toString();
  }
  
  /**
   * 和htmlEncode正好相反
   *
   * @param strSrc 要进行转换的字符串
   * @return 转换后的字符串
   * @since 1.0
   */
  public static String htmlDecode(String strSrc) {
    if (strSrc == null) {
      return "";
    }
    strSrc = strSrc.replaceAll("<", "<");
    strSrc = strSrc.replaceAll(">", ">");
    strSrc = strSrc.replaceAll("\"", "\"");
    strSrc = strSrc.replaceAll("'", "'");
    strSrc = strSrc.replaceAll("&", "&");
    return strSrc;
  }
  
  /**
   * 实际处理 return toChineseNoReplace(null2Blank(str));
   *
   * @param str 要进行处理的字符串
   * @return 转换后的字符串
   * @see fs_com.utils.CTools#toChinese
   * @see fs_com.utils.CTools#null2Blank
   */
  public static String toChineseAndHtmlEncode(String str, int quotes) {
    try {
      if (str == null) {
        return "";
      } else {
        str = str.trim();
        str = new String(str.getBytes("ISO8859_1"), "GBK");
        String htmlEncode = htmlEncode(str, quotes);
        return htmlEncode;
      }
    } catch (Exception exp) {
      return "";
    }
  }
  
  /**
   * 把null值和""值转换成  主要应用于页面表格格的显示
   *
   * @param str 要进行处理的字符串
   * @return 转换后的字符串
   */
  public static String str4Table(String str) {
    if (str == null) {
      return " ";
    } else if (str.equals("")) {
      return " ";
    } else {
      return str;
    }
  }
  
}
